﻿package {
	
	import com.myavatareditor.avatarcore.Adjust;
	import com.myavatareditor.avatarcore.display.ArtSprite;
	import com.myavatareditor.avatarcore.display.MirroredArtSprite;
	import com.myavatareditor.avatarcore.Feature;
	import flash.geom.Matrix;
	import flash.geom.Point;
	
	/**
	 * Moves a feature based on a selected ArtSprite.
	 * @author Trevor McCauley; www.senocular.com
	 */
	public class MoveFeatureTool implements IFeatureTool {
		
		private var selectedArtSprite:ArtSprite; // sprite being modified
		private var mouseOffset:Point; // retained click offset from sprite center
		private var startMousePosition:Point;
		private var startFeatureX:Number;
		private var startFeatureY:Number;
		
		public function MoveFeatureTool(){}
		
		public function startAction(artSprite:ArtSprite):void {
			selectedArtSprite = artSprite;
			
			// get mouse offset to prevent dragging from snapping
			// to dragged object's center
			mouseOffset = new Point();
			mouseOffset.x = selectedArtSprite.parent.mouseX - selectedArtSprite.x;
			mouseOffset.y = selectedArtSprite.parent.mouseY - selectedArtSprite.y;
			
			// retain the start mouse position to tell how 
			// much the mouse has moved when in whileAction
			startMousePosition = getMousePosition();
			
			// movement will be based off the current adjust value
			// changes in the mouse will be added to this
			startFeatureX = selectedArtSprite.feature.adjust.x;
			startFeatureY = selectedArtSprite.feature.adjust.y;
		}
		
		public function whileAction():void {
			
			// update feature position based on how much the mouse
			// has moved from the original start mouse position
			// this offset is added to the starting Adjust which 
			// will apply the correct offset to the Feature's own
			// Adjust value
			var moveOffset:Point = getMousePosition().subtract(startMousePosition);
			var feature:Feature = selectedArtSprite.feature;
			feature.adjust.x = startFeatureX + moveOffset.x;
			feature.adjust.y = startFeatureY + moveOffset.y;
			feature.redraw();
		}
		
		public function endAction():void {
			
			// clear references
			selectedArtSprite = null;
			mouseOffset = null;
		}
		
		/**
		 * Gets the mouse position with respect to the pseudo coordinate
		 * space used to draw an ArtSprite through the Avatar Core Framework
		 * with considerations for parent transformations and Mirror behaviors
		 * as well as the offset from the mouse where the selected ArtSprite
		 * was originally clicked.
		 */
		private function getMousePosition():Point {
			
			// mouse position
			var position:Point = new Point(selectedArtSprite.parent.mouseX, selectedArtSprite.parent.mouseY);
			//position = position.subtract(mouseOffset); // offset from center
			
			// account for parent transformations
			var parentMatrix:Matrix = selectedArtSprite.feature.getConcatenatedParentMatrix();
			parentMatrix.invert();
			position = parentMatrix.transformPoint(position);
			
			// if sprite generated by Mirror behavior, flip on x
			if (selectedArtSprite is MirroredArtSprite){
				position.x = -position.x;
			}
			
			return position;
		}
	}
}